package com.jstyle.jclifexd.fragment;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.support.constraint.ConstraintLayout;
import android.support.v4.app.Fragment;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.flexbox.FlexboxLayoutManager;
import com.jstyle.jclifexd.R;
import com.jstyle.jclifexd.activity.HealthHistoryActivity;
import com.jstyle.jclifexd.adapter.BpWeekAdapter;
import com.jstyle.jclifexd.adapter.HistoryShowAdapter;
import com.jstyle.jclifexd.adapter.HrvYearDataAdapter;
import com.jstyle.jclifexd.daoManager.HealthDataDaoManager;
import com.jstyle.jclifexd.model.HealthData;
import com.jstyle.jclifexd.model.HealthShowData;
import com.jstyle.jclifexd.utils.ChartDataUtil;
import com.jstyle.jclifexd.utils.DateUtil;
import com.jstyle.jclifexd.utils.ResolveData;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import butterknife.BindArray;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import lecho.lib.hellocharts.model.ArcValue;
import lecho.lib.hellocharts.model.BpValue;
import lecho.lib.hellocharts.model.PieChartData;
import lecho.lib.hellocharts.view.LineChartView;
import lecho.lib.hellocharts.view.PieChartView;

/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link HealthHistoryMonthFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class HealthHistoryMonthFragment extends BaseFragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    @BindView(R.id.RecyclerView_history_detail)
    RecyclerView RecyclerViewHistoryDetail;
    @BindView(R.id.bt_history_dataType)
    Button btHistoryDataType;
    @BindView(R.id.RecyclerView_history)
    RecyclerView RecyclerViewHistory;
    Unbinder unbinder;

    @BindView(R.id.PieChartView_history)
    PieChartView PieChartViewHistory;
    @BindView(R.id.tv_count_normal)
    TextView tvCountNormal;
    @BindView(R.id.tv_bp_normal)
    TextView tvBpNormal;
    @BindView(R.id.tv_count_low)
    TextView tvCountLow;
    @BindView(R.id.tv_bp_low)
    TextView tvBpLow;
    @BindView(R.id.tv_count_high)
    TextView tvCountHigh;
    @BindView(R.id.tv_bp_high)
    TextView tvBpHigh;
    @BindView(R.id.tv_count_error)
    TextView tvCountError;
    @BindView(R.id.tv_bp_error)
    TextView tvBpError;
    @BindView(R.id.ConstraintLayout_bp)
    ConstraintLayout ConstraintLayoutBp;
    @BindView(R.id.lineChartView_health_month)
    LineChartView lineChartViewHealthMonth;

    // TODO: Rename and change types of parameters
    private int mParam1;
    private String mParam2;

    private OnFragmentInteractionListener mListener;
    private ArrayList<String> listContent;
    private HistoryShowAdapter historyShowAdapter;
    private HashMap<String, List<Integer>> dateHashMap = new HashMap<>();
    HashMap<String, List<BpValue>> dateBpHashMap = new HashMap<>();
    private boolean isBusy;
    private static final String TAG = "HealthHistoryMonthFragm";
    private String[] monthArray;
    @BindArray(R.array.bp_color_arrays)
    int[] bpColorArray;
    @BindArray(R.array.stress_color_arrays)
    int[] stressColorArray;
    @BindArray(R.array.color_hrv_array)
    int[] hrvColorArray;
    @BindArray(R.array.health_hrv)
    String[] arrayHrv;
    @BindArray(R.array.health_pressure)
    String[] arrayPressure;
    @BindArray(R.array.string_bp_array)
    String[] arrayBp;
    @BindArray(R.array.string_hrv_array)
    String[] arrayHrvString;
    @BindArray(R.array.string_pressure_array)
    String[] arrayStressString;
    @BindArray(R.array.health_blood)
    String[] arrayBlood;
    int[] statusArray;
    int[] dataColorArray;
    String[] dataTextArray;
    private HealthData lastHealthData;
    private Typeface mFace;


    public HealthHistoryMonthFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @return A new instance of fragment HealthHistoryMonthFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static HealthHistoryMonthFragment newInstance(int param1) {
        HealthHistoryMonthFragment fragment = new HealthHistoryMonthFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_PARAM1, param1);

        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getInt(ARG_PARAM1);

        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_health_history_month, container, false);
        unbinder = ButterKnife.bind(this, view);
        init();
        return view;
    }

    private void init() {
        mFace = Typeface.createFromAsset(getActivity().getAssets(), "Brandon_reg.otf");

        FlexboxLayoutManager layoutManager2 = new FlexboxLayoutManager(getActivity());
        setListContent();
        historyShowAdapter = new HistoryShowAdapter(listContent);
        RecyclerViewHistoryDetail.setAdapter(historyShowAdapter);
        RecyclerViewHistoryDetail.setLayoutManager(layoutManager2);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity()) {
            @Override
            public boolean canScrollVertically() {
                return false;
            }
        };
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        RecyclerViewHistory.setLayoutManager(linearLayoutManager);
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL);
        ColorDrawable colorDrawable = new ColorDrawable();
        colorDrawable.setColor(Color.DKGRAY);
        dividerItemDecoration.setDrawable(colorDrawable);
        RecyclerViewHistory.addItemDecoration(dividerItemDecoration);
        String[] monthDates = DateUtil.getThisMonth();
        String queryDate = getShowDate(monthDates[0]);
        initText();
        updateDate(queryDate, mParam1);
    }

    private void initText() {
        switch (mParam1) {
            case HealthHistoryActivity.DATA_BLOOD:
                dataColorArray = bpColorArray;
                dataTextArray = arrayBp;
                break;
            case HealthHistoryActivity.DATA_HRV:
                dataColorArray = hrvColorArray;
                dataTextArray = arrayHrvString;
                break;
            case HealthHistoryActivity.DATA_PRESSURE:
                dataColorArray = stressColorArray;
                dataTextArray = arrayStressString;
                break;
        }
    }

    private void setListContent() {
        listContent = new ArrayList<>();
        String[] arrayContent = null;
        switch (mParam1) {
            case HealthHistoryActivity.DATA_BLOOD:
                arrayContent = arrayBlood;
                break;
            case HealthHistoryActivity.DATA_HRV:
                arrayContent = arrayHrv;
                break;
            case HealthHistoryActivity.DATA_PRESSURE:
                arrayContent = arrayPressure;
                break;
        }
        listContent.addAll(Arrays.asList(arrayContent));

    }

    private String getShowDate(String monthString) {
        Locale locale = getResources().getConfiguration().locale;
        String language = locale.getLanguage();
        long time = DateUtil.getDateLong(monthString);
        String format = "";

        format = "yyyy-MM";

        return DateUtil.getFormatTimeString(time, format);
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

    }

    @Override
    public void updateDate(final String queryDate, final int dataType) {
        final String[] dateArray = queryDate.split("-");
        ConstraintLayoutBp.setVisibility(dataType== HealthHistoryActivity.DATA_BLOOD?View.VISIBLE:View.GONE);
        lineChartViewHealthMonth.setVisibility(dataType== HealthHistoryActivity.DATA_BLOOD?View.GONE:View.VISIBLE);
        dateHashMap.clear();
        monthArray = DateUtil.getMonth(Integer.valueOf(dateArray[0]), Integer.valueOf(dateArray[1]) - 1);
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                healthDataList = HealthDataDaoManager.queryDayData(monthArray[0] + " 00:00:00", monthArray[monthArray.length - 1] + " 23:59:59");
                lastHealthData = healthDataList.size() == 0 ? new HealthData() : healthDataList.get(0);

                initHealthData(healthDataList, dataType);

                e.onComplete();
            }
        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Integer value) {
                Log.i(TAG, "onNext: " + value);
            }

            @Override
            public void onError(Throwable e) {
                disMissLoadingDialog();
                isBusy = false;
                Log.i(TAG, "onError: " + e.getMessage());
            }

            @Override
            public void onComplete() {
                disMissLoadingDialog();
                if (mParam1 == HealthHistoryActivity.DATA_BLOOD) {

                    setWeekBpChartViewData();
                } else {

                    setWeekChartViewData();
                }
//                setWeekBpChartViewData();
                initRecyclerViewHistory();
                isBusy = false;
            }
        });

    }

    private void setWeekChartViewData() {
        int max = 0;
        int min = 300;
        HashMap<String, Integer> weekMap = new HashMap<>();
        int totalWeek = 0;
        int size = 0;
        for (String date : monthArray) {
            List<Integer> list = dateHashMap.get(date);
            if (list != null) {
                size += list.size();
                int totalDay = 0;
                for (Integer i : list) {
                    max = Math.max(i, max);
                    min = Math.min(i, min);
                    totalDay += i;
                }
                int value = totalDay / list.size();
                weekMap.put(date, value);
                totalWeek += totalDay;
            }

        }
        int top = (max / 10 + 1) * 10;
        ChartDataUtil.initDataChartView(lineChartViewHealthMonth, -0.5f, top + 5, monthArray.length, 0);
        lineChartViewHealthMonth.setLineChartData(ChartDataUtil.getHealthWeekLineChart(getActivity(), weekMap, top, monthArray));
        int avgHR = size == 0 ? 0 : totalWeek / size;
        List<String> listHeart = new ArrayList<>();//总计列表
        listHeart.add(avgHR + "");
        listHeart.add(max + "");
        listHeart.add((min == 300 ? 0 : min) + "");
        historyShowAdapter.setStepData(listHeart);
    }


    List<HealthData> healthDataList;
    private List<BpValue> bpValueList;

    private void initRecyclerViewHistory() {
        if (mParam1 == HealthHistoryActivity.DATA_BLOOD) {
            BpWeekAdapter bpWeekAdapter = new BpWeekAdapter(bpValueList);
            RecyclerViewHistory.setAdapter(bpWeekAdapter);
        } else {
            List<HealthShowData> healthShowDataList = new ArrayList<>();
            for (String date : monthArray) {
                int dayMax = 0;
                int dayMin = 300;
                List<Integer> list = dateHashMap.get(date);
                if (list != null) {
                    for (Integer i : list) {
                        dayMax = Math.max(i, dayMax);
                        dayMin = Math.min(i, dayMin);
                    }
                    HealthShowData healthShowData = new HealthShowData();
                    healthShowData.setTime(DateUtil.getShowDay(getContext(),date));
                    healthShowData.setContent(mParam1==HealthHistoryActivity.DATA_HRV?getString(R.string.hrv):getString(R.string.stress));
                    healthShowData.setMaxValue(dayMax);
                    healthShowData.setMinValue(dayMin);
                    healthShowDataList.add(healthShowData);
                }

            }
            HrvYearDataAdapter hrvYearDataAdapter=new HrvYearDataAdapter(healthShowDataList);
            RecyclerViewHistory.setAdapter(hrvYearDataAdapter);
        }

    }

    HealthData maxHealthData = null;
    HealthData minHealthData = null;

    private void initHealthData(List<HealthData> healthDataList, int dataType) {
        statusArray = new int[4];
        if (dataType == HealthHistoryActivity.DATA_BLOOD) {
            initBpData(healthDataList);
        } else {
            initHealthOtherData(healthDataList, dataType);
        }
    }

    private void initHealthOtherData(List<HealthData> healthDataList, int dataType) {
        for (HealthData healthData : healthDataList) {
            String time = healthData.getTime();
            String[] timeArray = time.split(" ");
            String date = timeArray[0];
            if (dataType == HealthHistoryActivity.DATA_HRV) {
                statusArray[ResolveData.getHrvLevel(healthData.getHrv())]++;
            } else if (dataType == HealthHistoryActivity.DATA_PRESSURE) {
                statusArray[ResolveData.getStressLevel(healthData.getPressure())]++;
            }
            List<Integer> list = dateHashMap.get(date);
            int value = ResolveData.getData(healthData, dataType);
            if (value != 0) {
                if (list == null) {
                    list = new ArrayList<>();
                }
                list.add(value);
                dateHashMap.put(date, list);
            }
        }
    }

    private void initBpData(List<HealthData> healthDataList) {//血压数据

        maxHealthData = null;
        minHealthData = null;
        dateBpHashMap.clear();
        int maxDayHr = 0;
        int minDayHr = 300;
        for (HealthData healthData : healthDataList) {
            String time = healthData.getTime();
            String[] timeArray = time.split(" ");
            String date = timeArray[0];
            List<BpValue> list = dateBpHashMap.get(date);
            int highValue = healthData.getHighBloodPressure();
            int lowValue = healthData.getLowBloodPressure();
            if (highValue != 0 && lowValue != 0) {
               statusArray[ResolveData.getBPStatus(highValue, lowValue)]++;
                if (list == null) {
                    list = new ArrayList<>();
                }
                BpValue bpValue = new BpValue(highValue, lowValue);
                bpValue.setDate(date);
                list.add(bpValue);
                dateBpHashMap.put(date, list);
                if (highValue > maxDayHr) {
                    maxDayHr = highValue;
                    maxHealthData = healthData;
                }
                if (lowValue < minDayHr) {
                    minDayHr = lowValue;
                    minHealthData = healthData;
                }
            }
        }
        getBpRecycleViewData();
    }

    private void getBpRecycleViewData() {
        bpValueList = new ArrayList<>();
        for (Map.Entry<String, List<BpValue>> entry : dateBpHashMap.entrySet()) {
            List<BpValue> valueList = entry.getValue();
            int maxHr = 0;
            int minHr = 300;
            BpValue maxBp = null;
            BpValue minBp = null;
            for (BpValue bpValue : valueList) {
                int low = bpValue.getLowValue();
                int high = bpValue.getHighValue();
                if (high > maxHr) {
                    maxHr = high;
                    maxBp = bpValue;
                }
                if (low < minHr) {
                    minHr = low;
                    minBp = bpValue;
                }
            }
            bpValueList.add(minBp);
            bpValueList.add(maxBp);
        }
        Collections.sort(bpValueList, new Comparator<BpValue>() {
            @Override
            public int compare(BpValue o1, BpValue o2) {
                Date date = DateUtil.String2Date(o1.getDate(), DateUtil.Default_FormatString);
                Date date2 = DateUtil.String2Date(o2.getDate(), DateUtil.Default_FormatString);
                return date.before(date2) ? 1 : -1;
            }
        });
    }


    private void setWeekBpChartViewData() {
        int max = 0;
        int min = 300;
        HashMap<String, BpValue> weekMap = new HashMap<>();
        int totalWeek = 0;
        int size = 0;
        for (String date : monthArray) {
            List<BpValue> list = dateBpHashMap.get(date);
            if (list != null) {
                size += list.size();
                int totalDayHigh = 0;
                int totalDayLow = 0;
                for (BpValue i : list) {
//                    max = Math.max(i, max);
//                    min = Math.min(i, min);
                    totalDayHigh += i.getHighValue();
                    totalDayLow += i.getLowValue();
                }
                int valueHigh = totalDayHigh / list.size();
                int valueLow = totalDayLow / list.size();
                weekMap.put(date, new BpValue(valueHigh, valueLow));
                //  totalWeek += totalDay;
            }

        }
        List<ArcValue> arcValues = new ArrayList<>();
        for (int i = 0; i < statusArray.length; i++) {
            int count = statusArray[i];
            if (count != 0)
                arcValues.add(new ArcValue(count, dataColorArray[i]));
        }
        tvBpNormal.setText(dataTextArray[0]);
        tvBpLow.setText(dataTextArray[1]);
        tvBpHigh.setText(dataTextArray[2]);
        tvBpError.setText(dataTextArray[3]);
        tvBpNormal.setTextColor(dataColorArray[0]);
        tvBpLow.setTextColor(dataColorArray[1]);
        tvBpHigh.setTextColor(dataColorArray[2]);
        tvBpError.setTextColor(dataColorArray[3]);
        tvCountNormal.setText(String.valueOf(statusArray[0]) );
        tvCountLow.setText(String.valueOf(statusArray[1]) );
        tvCountHigh.setText(String.valueOf(statusArray[2]) );
        tvCountError.setText(String.valueOf(statusArray[3]) );
        PieChartData pieChartData = new PieChartData(arcValues);
        pieChartData.setHasLabelsOnlyForSelected(arcValues.size() != 0);
        if (arcValues.size() == 0) {
            arcValues.add(new ArcValue(1, getResources().getColor(R.color.history_data_hint)).setArcSpacing(0));
            pieChartData.setCenterText1(getString(R.string.No_data));
        } else {
            String lastText = ResolveData.getLastDataString(lastHealthData, mParam1);
            int textColor = Color.WHITE;
            String label = "";
            if (mParam1 == HealthHistoryActivity.DATA_PRESSURE) {
                int level = ResolveData.getStressLevel(lastHealthData.getPressure());
                Log.i(TAG, "setWeekBpChartViewData: " + lastHealthData.getTime());
                textColor = dataColorArray[level];
                label = "\n" + dataTextArray[level];
            } else if (mParam1 == HealthHistoryActivity.DATA_HRV) {
                int level = ResolveData.getHrvLevel(lastHealthData.getHrv());
                textColor = dataColorArray[level];
                label = "\n" + dataTextArray[level];
            } else if (mParam1 == HealthHistoryActivity.DATA_BLOOD) {
                textColor = getResources().getColor(R.color.style_text_color);
            }
            pieChartData.setCenterText1(getString(R.string.The_last_time));
            pieChartData.setCenterText2Color(textColor);
            pieChartData.setCenterText2FontSize(12);
            pieChartData.setCenterText2(lastText + label);
        }
        pieChartData.setHasCenterCircle(true);
        pieChartData.setCenterText1Color(getResources().getColor(R.color.style_text_color));
        pieChartData.setCenterText1Typeface(mFace);
        pieChartData.setCenterText2Typeface(mFace);
        pieChartData.setCenterText1FontSize(12);
        pieChartData.setCenterCircleColor(getResources().getColor(R.color.main_bg_color));
        PieChartViewHistory.setChartRotationEnabled(false);
        PieChartViewHistory.setValueSelectionEnabled(true);
        PieChartViewHistory.setPieChartData(pieChartData);

        setWeekBpData();


    }

    private void setWeekBpData() {
        List<String> listHeart = new ArrayList<>();//总计列表
        listHeart.add(healthDataList.size() + "");
        String highDay = maxHealthData == null ? "--/--" : maxHealthData.getHighBloodPressure() + "/" + maxHealthData.getLowBloodPressure();
        String lowDay = minHealthData == null ? "--/--" : minHealthData.getHighBloodPressure() + "/" + minHealthData.getLowBloodPressure();
        listHeart.add(highDay);
        listHeart.add(lowDay);
        historyShowAdapter.setStepData(listHeart);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }
}
